-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: File
constructor path sanitizer
#18504
base: main
Are you sure you want to change the base?
Java: File
constructor path sanitizer
#18504
Conversation
4dc7562
to
7837ad6
Compare
8ef7637
to
60cc16c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
Comments suppressed due to low confidence (1)
java/ql/test/library-tests/pathsanitizer/Test.java:482
- Several consecutive blocks (lines 480–610) repeat similar path validation logic. Consider extracting this shared logic into a utility method or parameterized test to simplify and reduce duplication.
File f1 = new File("safe/file.txt");
Tip: Copilot code review supports C#, Go, Java, JavaScript, Markdown, Python, Ruby and TypeScript, with more languages coming soon. Learn more
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to sanitize the constructor call instead, with checks on the first argument.
src.asExpr().(MethodCall).getMethod().getName() = "source" | ||
} | ||
|
||
predicate isSink(DataFlow::Node sink) { exists(Call call | sink.asExpr() = call.getAnArgument()) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I worry this could be a performance problem - finding all global flow to arguments of calls. Better to make it more specific - something like any(ConstructorCall constrCall | constrCall.getConstructedType() instanceof TypeFile).getArgument(0)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm also concerned about that, which is why I'm currently running DCA.
Based on previous experimentation with this, I don't think restricting to ConstructorCall
will necessarily be any better, but I'll give it a try if my current DCA experiment shows bad performance.
Do we have any better/pre-built way of checking whether an expression is tainted that doesn't require making a global TaintTracking
config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, performance is bad. Running DCA on the ConstructorCall
version to see if there's a difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ConstructorCall
version still has bad performance (although not as bad as the Call
version).
// for InlineFlowTest | ||
src.asExpr().(MethodCall).getMethod().getName() = "source" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for testing, but we shouldn't commit this. I'm sure we can find some other solution, like adding a model to the inlineflowtest so that source
is a remote flow source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what you mean by "adding a model to the inlineflowtest"? I was thinking of using an actual ActiveThreatModelSource
in this test case instead of (File) source();
. Is that what you mean? Or did you have something else in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant you could add a model for source
as a remote flow source that applies just to this test (if the test is x.ql
then the model has to be in a file called x.ext.yml
in the same folder). That way the inline flow test can use its way of finding sources (calls to "source") and this flow config can use its way (active threat model). An alternative approach is to change the test to use ActiveThreatModel
for its sources, which I think is what you were suggesting. Both are fine.
Description
Adds a path injection sanitizer for the
child
argument of ajava.io.File
constructor when that argument is normalized or checked for the absence of "..".Consideration
Note that sanitizing the second argument of the
File
constructor also sanitizes other uses of that variable after the constructor call (see theMISSING
cases in the tests). Let me know if there is some way to adjust the QL to avoid also sanitizing these other uses. I can sanitize theFile
constructor call instead of the second argument, but then the first argument needs to be checked for taint.Pull Request checklist
All query authors
Internal query authors only